########################################################################
#  Searx-Qt - Lightweight desktop application for Searx.
#  Copyright (C) 2020-2022  CYBERDEViL
#
#  This file is part of Searx-Qt.
#
#  Searx-Qt is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Searx-Qt is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
########################################################################


from PyQt5.QtCore import QObject, pyqtSignal

from searxqt.themes import Themes
from searxqt.core.instances import Stats2
from searxqt.core import log


class General:
    def serialize():
        return {
            'logLevel': log.LogLevel,
            'themes': Themes.serialize()
        }

    def deserialize(data):
        # Populate / re-populate user and system themes
        Themes.populate()
        themesData = data.get('themes', {})
        if themesData:
            Themes.deserialize(themesData)

        # Log level
        logLevel = data.get('logLevel', None)
        if logLevel is not None:
            log.LogLevel = logLevel
        else:
            log.LogLevel = log.LogLevels.QUIET


class SettingsModel(QObject):
    changed = pyqtSignal()

    def __init__(self, requestSettings, imgRequestSettings, parent=None):
        QObject.__init__(self, parent=parent)

        self._requests = RequestSettingsModel(requestSettings)
        self._imgRequests = RequestSettingsModel(imgRequestSettings)
        self._stats2 = None

        self._requests.changed.connect(self.changed)

    def loadSettings(self, data, stats2=True):
        self.requests.data = data.get('requests', {})
        self.imgRequests.data = data.get('imgRequests', {})

        if self._stats2:
            self._stats2.deleteLater()
            self._stats2 = None

        if stats2:
            self._stats2 = SearxStats2Model()
            stats2Data = data.get('stats2', {})
            self.stats2.loadSettings(stats2Data)

        General.deserialize(data.get('general', {}))

    def saveSettings(self):
        if self._stats2:
            return {
                'general': General.serialize(),
                'requests': self.requests.data,
                'imgRequests': self.imgRequests.data,
                'stats2': self.stats2.saveSettings()
            }
        return {
            'general': General.serialize(),
            'requests': self.requests.data,
            'imgRequests': self.imgRequests.data
        }

    @property
    def requests(self): return self._requests

    @property
    def imgRequests(self): return self._imgRequests

    @property
    def stats2(self): return self._stats2


class SearxStats2Model(QObject):
    changed = pyqtSignal()

    def __init__(self, parent=None):
        QObject.__init__(self, parent=parent)
        self._backupUrl = Stats2.URL

    def loadSettings(self, data):
        self.url = data.get('url', self._backupUrl)

    def saveSettings(self):
        return {
            'url': self.url
        }

    def reset(self):
        self.url = self._backupUrl

    @property
    def url(self):
        return Stats2.URL

    @url.setter
    def url(self, url):
        Stats2.URL = url
        self.changed.emit()


class RequestSettingsModel(QObject):
    changed = pyqtSignal()

    # @param requestSettings: TODO
    # @type requestSettings: core.requests.RequestSettings
    def __init__(self, requestSettings, parent=None):
        QObject.__init__(self, parent=parent)
        self._settings = requestSettings

    def __changed(self):
        self._settings.updateRequestKwargs()
        self.changed.emit()

    def __getattr__(self, key):
        if key == "data":
            return self._settings.getData()
        return getattr(self._settings, key)

    def __setattr__(self, key, value):
        if key == "useragents":
            self._settings.useragents.clear()
            for ua in value:
                self._settings.useragents.append(ua)
            self.__changed()
            return

        if key == "data":
            self._settings.setData(value)
            return

        if key == "_settings":
            super().__setattr__(key, value)
            return

        setattr(self._settings, key, value)
        self.__changed()
